---
title: Accordion
description: Using the accordion machine in your project.
package: "@zag-js/accordion"
---

An accordion is a vertically stacked set of interactive headings containing a
title, content snippet, or thumbnail representing a section of content.

<Resources pkg="@zag-js/accordion" />

<Showcase id="Accordion" />

**Features**

- Full keyboard navigation
- Can expand one or multiple items
- Collapse each accordion item

## Installation

To use the accordion machine in your project, run the following command in your
command line:

<CodeSnippet id="accordion/installation.mdx" />

## Anatomy

To set up the accordion correctly, you'll need to understand its anatomy and how
we name its parts.

> Each part includes a `data-part` attribute to help identify them in the DOM.

<Anatomy id="accordion" />

## Usage

First, import the accordion package into your project

```jsx
import * as accordion from "@zag-js/accordion"
```

The accordion package exports two key functions:

- `machine` — The state machine logic for the accordion widget.
- `connect` — The function that translates the machine's state to JSX attributes
  and event handlers.

> You'll also need to provide a unique `id` to the `useMachine` hook. This is
> used to ensure that every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the
accordion machine in your project 🔥

<CodeSnippet id="accordion/usage.mdx" />

You may have noticed we wrapped each accordion trigger within an `h3`. This is
recommended by the
[WAI-ARIA](https://www.w3.org/TR/wai-aria-practices-1.1/#wai-aria-roles-states-and-properties)
design pattern to ensure the accordion has the appropriate hierarchy on the
page.

### Opening multiple accordions at once

To allow multiple items to be expanded at once, set `multiple` to `true`. This
mode implicitly sets `collapsible` to `true` and ensures that each accordion can
be expanded.

```jsx {2}
const service = useMachine(accordion.machine, {
  multiple: true,
})
```

### Opening accordions by default

To set the value of the accordion(s) that should be opened initially, pass the
`defaultValue` property to the machine function.

```jsx {3,4,9}
// for multiple accordions
const service = useMachine(accordion.machine, {
  multiple: true,
  defaultValue: ["home"],
})

// for single accordions
const service = useMachine(accordion.machine, {
  defaultValue: ["home"],
})
```

### Controlled accordions

To control the accordion's value, pass the `value` and `onValueChange`
properties to the machine function.

<CodeSnippet id="accordion/controlled.mdx" />

### Toggle each accordion item

To collapse an already expanded accordion item by clicking on it, set the
context's `collapsible` property to `true`.

> Note: If `multiple` is `true`, we internally set `collapsible` to be `true`.

```jsx {2}
const service = useMachine(accordion.machine, {
  collapsible: true,
})
```

#### Listening for changes

When the accordion value changes, the `onValueChange` callback is invoked.

```jsx {2-5}
const service = useMachine(accordion.machine, {
  onValueChange(details) {
    // details => { value: string[] }
    console.log("selected accordion:", details.value)
  },
})
```

### Disabling an accordion item

To disable a specific accordion item, pass the `disabled: true` property to the
`getItemProps`, `getItemTriggerProps` and `getItemContentProps`.

When an accordion item is disabled, it is skipped from keyboard navigation and
can't be interacted with.

```jsx
//...
<div {...api.getItemProps({ value: "item", disabled: true })}>
  <h3>
    <button {...api.getItemTriggerProps({ value: "item", disabled: true })}>
      Trigger
    </button>
  </h3>
  <div {...api.getItemContentProps({ value: "item", disabled: true })}>
    Content
  </div>
</div>
//...
```

You can also disable the entire accordion items by passing `disabled` to the
machine's context.

```jsx {2}
const service = useMachine(accordion.machine, {
  disabled: true,
})
```

## Styling guide

Earlier, we mentioned that each accordion part has a `data-part` attribute added
to them to select and style them in the DOM.

### Open and closed state

When an accordion item is expanded or collapsed, a `data-state` attribute is set
on the item, trigger and content elements. This attribute is removed when it is
closed.

```css
[data-part="item"][data-state="open|closed"] {
  /* styles for the item is open or closed state */
}

[data-part="item-trigger"][data-state="open|closed"] {
  /* styles for the item is open or closed state */
}

[data-part="item-content"][data-state="open|closed"] {
  /* styles for the item is open or closed state */
}
```

### Focused state

When an accordion item's trigger is focused, a `data-focus` attribute is set on
the item and content.

```css
[data-part="item"][data-focus] {
  /* styles for the item's focus state */
}

[data-part="item-trigger"]:focus {
  /* styles for the trigger's focus state */
}

[data-part="item-content"][data-focus] {
  /* styles for the content's focus state */
}
```

## Creating Component

Create your accordion component by abstracting the machine into your own
component.

### Usage

<CodeSnippet id="accordion/component.usage.mdx" />

### Implementation

Use the the `splitProps` utility to separate the machine's props from the
component's props.

<CodeSnippet id="accordion/component.api.mdx" />

## Methods and Properties

The accordion's `api` exposes the following methods and properties:

### Machine Context

The accordion machine exposes the following context properties:

<ContextTable name="accordion" />

### Machine API

The accordion `api` exposes the following methods:

<ApiTable name="accordion" />

### Data Attributes

<DataAttrTable name="accordion" />

## Accessibility

### Keyboard Interactions

<KeyboardTable name="accordion" />
